home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / 3dprograms / t3dlib / source / writeoff.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  5KB  |  224 lines

  1. /* writeoff.c - dump the internal database to an OFF file
  2.  *            - written by Glenn M. Lewis - 10/29/91
  3.  */
  4.  
  5. static char rcs_id[] = "$Id: writeoff.c,v 1.10 1993/01/30 23:43:03 glewis Exp $";
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include "t3dlib.h"
  10. #ifdef __STDC__
  11. #include <stdlib.h>
  12. #include <strings.h>
  13. #include "writeoff_protos.h"
  14. #endif
  15.  
  16. static void process_DESC();
  17. static void process_points_DESC();
  18. static void process_faces_DESC();
  19. static void count_points_faces();
  20.  
  21. static int geom_count;
  22. static char filename[256];
  23. static char *rootname;
  24. static FILE *out, *outcol;
  25. static unsigned long poff;    /* Point index offset */
  26.  
  27. /* Here are a few necessary utilities */
  28.  
  29. static void send_XYZ(f)            /* Print a common string */
  30. XYZ_st *f;
  31. {
  32.     fprintf(out, "%.12g\t%.12g\t%.12g\n", f->x, f->y, f->z);
  33. }
  34.  
  35. static void send_RGB(rgb)            /* Print a common string */
  36. RGB_st *rgb;
  37. {
  38.     fprintf(outcol, "%.12g\t%.12g\t%.12g\n",
  39.         ((double)rgb->r)/255.0,
  40.         ((double)rgb->g)/255.0,
  41.         ((double)rgb->b)/255.0);
  42. }
  43.  
  44. /********************/
  45. /* The MAIN section */
  46. /********************/
  47.  
  48. int geom_flag;
  49.  
  50. int write_OFF(world, name, splitflag, geom_only)
  51. WORLD *world;
  52. char *name;
  53. int splitflag, geom_only;
  54. {
  55.     register OBJECT *o;
  56.     unsigned long total_points, total_faces;
  57.  
  58.     if (!world) return(0);
  59.  
  60.     geom_flag = geom_only;
  61.     geom_count = 0;
  62.     rootname = name;
  63.     if (splitflag) {
  64.         for (o=world->object; o; o=o->next)
  65.             if (!o->extr) process_DESC(o);
  66.         return(1);
  67.     }
  68.  
  69.     strcpy(filename, rootname);
  70.     strcat(filename, ".geom");
  71.     if (!(out=fopen(filename, "w"))) {
  72.         fprintf(stderr, "Can't open '%s' for output.\n", filename);
  73.         return(0);
  74.     }
  75.     if (!geom_flag) {
  76.         strcpy(filename, rootname);
  77.         strcat(filename, ".ipcol");
  78.         if (!(outcol=fopen(filename, "w"))) {
  79.             fprintf(stderr, "Can't open '%s' for output.\n", filename);
  80.             fclose(out);
  81.             return(0);
  82.         }
  83.     }
  84.  
  85.     poff = total_points = total_faces = 0;
  86.  
  87.     for (o=world->object; o; o=o->next)
  88.         count_points_faces(o, &total_points, &total_faces);
  89.     fprintf(out, "%lu\t%lu\t%lu\n", total_points, total_faces, total_points*3L);
  90.     if (!geom_flag) fprintf(outcol, "%lu\n", total_faces);
  91.  
  92.     for (o=world->object; o; o=o->next)
  93.         process_points_DESC(o);
  94.     for (o=world->object; o; o=o->next)
  95.         process_faces_DESC(o);
  96.     
  97.     fclose(out);
  98.     if (!geom_flag) fclose(outcol);
  99.     return(1);
  100. }
  101.  
  102. static void count_points_faces(object, points, faces)
  103. register OBJECT *object;
  104. unsigned long *points, *faces;
  105. {
  106.     register OBJECT *obj;
  107.  
  108.     if (object->extr) return;
  109.     *points += object->desc->pcount;
  110.     *faces  += object->desc->fcount;
  111.  
  112.     for (obj=object->child; obj; obj=obj->next) {
  113.         if (!obj->extr) count_points_faces(obj, points, faces);
  114.     }
  115. }
  116.  
  117. static void process_points_DESC(object)
  118. OBJECT *object;
  119. {
  120.     register int i;
  121.     register OBJECT *obj;
  122.     register DESC *desc = object->desc;
  123.  
  124. /*    if (!desc->pcount || !desc->fcount) return;    */
  125.  
  126.     if (desc)
  127.     for (i=0; i<desc->pcount; i++) {
  128.         send_XYZ(&desc->pnts[i]);
  129.     }
  130.  
  131.     for (obj=object->child; obj; obj=obj->next) {
  132.         if (!obj->extr) process_points_DESC(obj);
  133.     }
  134. }
  135.  
  136. static void process_faces_DESC(object)
  137. OBJECT *object;
  138. {
  139.     register int i;
  140.     register OBJECT *obj;
  141.     register DESC *desc = object->desc;
  142.     register int p1, p2, p3;
  143.  
  144. /*    if (!desc->pcount || !desc->fcount) return;    */
  145.  
  146.     if (desc) {
  147.         for (i=0; i<desc->fcount; i++) {
  148.         /* First check to make sure that this triangle is real */
  149.             p1 = desc->edge[(desc->face[i*3])<<1];
  150.             p2 = desc->edge[((desc->face[i*3])<<1)+1];
  151.             /* if (p1 == p2) continue;    /* How did *this* happen? */
  152.             p3 = desc->edge[(desc->face[i*3+2])<<1];
  153.             if (p1 == p3 || p2 == p3)
  154.                 p3 = desc->edge[((desc->face[i*3+2])<<1)+1];
  155.             /* if (p1 == p3 || p2 == p3) continue; /* How did *this* happen? */
  156.  
  157.             fprintf(out, "3\t%lu\t%lu\t%lu\n", poff+p1+1, poff+p2+1, poff+p3+1);
  158.             if (!geom_flag) send_RGB((RGB_st*)&desc->clst[i*3]);
  159.         }
  160.         poff += desc->pcount;
  161.     }
  162.  
  163.     for (obj=object->child; obj; obj=obj->next) {
  164.         if (!obj->extr) process_faces_DESC(obj);
  165.     }
  166. }
  167.  
  168. static void process_DESC(object)
  169. OBJECT *object;
  170. {
  171.     register int i;
  172.     register OBJECT *obj;
  173.     register DESC *desc = object->desc;
  174.     register int p1, p2, p3;
  175.  
  176.     /* Process children first */
  177.     for (obj=object->child; obj; obj=obj->next) {
  178.         if (!obj->extr) process_DESC(obj);
  179.     }
  180.  
  181.     if (!desc->pcount || !desc->fcount) return;
  182.  
  183.     geom_count++;
  184.     sprintf(filename, "%s%03d.geom", rootname, geom_count);
  185.     if (!(out = fopen(filename, "w"))) {
  186.         fprintf(stderr, "Can't open '%s' for output.\n", filename);
  187.         return;
  188.     }
  189.     fprintf(out, "; %s\n", filename);
  190.     fprintf(out, "%u\t%u\t%u\n",
  191.         desc->pcount, desc->fcount, desc->pcount*3);
  192.     if (!geom_flag) {
  193.         sprintf(filename, "%s%03d.ipcol", rootname, geom_count);
  194.         if (!(outcol = fopen(filename, "w"))) {
  195.             fprintf(stderr, "Can't open '%s' for output.\n", filename);
  196.             return;
  197.         }
  198.         fprintf(outcol, "; %s\n", filename);
  199.         fprintf(outcol, "%u\n", desc->fcount);
  200.     }
  201.  
  202.     for (i=0; i<desc->pcount; i++) {
  203.         send_XYZ(&desc->pnts[i]);
  204.     }
  205.  
  206.     for (i=0; i<desc->fcount; i++) {
  207.     /* First check to make sure that this triangle is real */
  208.         p1 = desc->edge[(desc->face[i*3])<<1];
  209.         p2 = desc->edge[((desc->face[i*3])<<1)+1];
  210.         /* if (p1 == p2) continue;    /* How did *this* happen? */
  211.         p3 = desc->edge[(desc->face[i*3+2])<<1];
  212.         if (p1 == p3 || p2 == p3)
  213.             p3 = desc->edge[((desc->face[i*3+2])<<1)+1];
  214.         /* if (p1 == p3 || p2 == p3) continue; /* How did *this* happen? */
  215.  
  216.         fprintf(out, "3\t%u\t%u\t%u\n", p1+1, p2+1, p3+1);
  217.         if (!geom_flag) send_RGB((RGB_st*)&desc->clst[i*3]);
  218.     }
  219.  
  220.     fclose(out);
  221.     if (!geom_flag) fclose(outcol);
  222. }
  223.  
  224.